package com.open.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;

import com.open.ui.R;

import java.lang.ref.WeakReference;

/**
 * https://www.open-open.com/lib/view/open1416664217867.html
 * >= android 5.0的版本，elevation 可以控制 shadow 的大小
 * outline 与 alpha 这两个因素，可以更精确的控制 shadow 的深浅，能无限接近设计师的阴影要求
 * <p>
 * setOutlineProvider() 会存在性能消耗，需要考虑与测试消耗.
 */
public class TVUILayoutHeper {

    private float mShadowAlpha = 0.0f;
    private int mRadius = 0;
    private int mShadowElevation = 0;
    private int mShadowColor = Color.BLACK;
    private int mOutlineInsetLeft = 0;
    private int mOutlineInsetRight = 0;
    private int mOutlineInsetTop = 0;
    private int mOutlineInsetBottom = 0;

    private WeakReference<View> mCacheView;

    public TVUILayoutHeper(Context context, AttributeSet attrs, int defStyleAttr, View view) {
        mCacheView = new WeakReference<View>(view);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TVUIShadow, defStyleAttr, 0);
        int count = typedArray.getIndexCount();
        for (int at = 0; at < count; at++) {
            int index = typedArray.getIndex(at);
            if (index == R.styleable.TVUIShadow_tvui_shadow_alpha) {
                mShadowAlpha = typedArray.getFloat(index, 0.0f);
            } else if (index == R.styleable.TVUIShadow_tvui_shadow_color) {
                mShadowColor = typedArray.getColor(index, Color.BLACK);
            } else if (index == R.styleable.TVUIShadow_tvui_shadow_radius) {
                mRadius = typedArray.getDimensionPixelSize(index, 0);
            } else if (index == R.styleable.TVUIShadow_tvui_shadow_elevation) {
                mShadowElevation = typedArray.getDimensionPixelSize(index, 0);
            }
        }
        typedArray.recycle();
        //
        setRadiusAndShadow(mRadius, mShadowElevation, mShadowAlpha);
    }

    public void setRadiusAndShadow(int radius, int shadowElevation, float shadowAlpha) {
        final View view = mCacheView.get();
        if (view == null) {
            return;
        }
        mRadius = radius;
        mShadowElevation = shadowElevation;
        mShadowAlpha = shadowAlpha;
        // 设置相关属性
        if (isUseShadow()) {
            // 设置阴影颜色
            view.setElevation(mShadowElevation);
//            view.setClipToOutline(mRadius > 0);
            setShadowColorInner(mShadowColor);
            view.setOutlineProvider(new ViewOutlineProvider() {
                @Override
                public void getOutline(View view, Outline outline) {
                    int w = view.getWidth();
                    int h = view.getHeight();
                    if (w == 0 || h == 0) {
                        return;
                    }

                    // 设置透明度
                    outline.setAlpha(mShadowAlpha);

                    int top = mOutlineInsetTop;
                    int bottom = Math.max(top + 1, h - mOutlineInsetBottom);
                    int left = mOutlineInsetLeft;
                    int right = w - mOutlineInsetRight;

                    // 处理 padding情况

                    // 矩形阴影
                    if (mRadius <= 0) {
                        outline.setRect(left, top, right, bottom);
                    } else {
                        outline.setRoundRect(left, top, right, bottom, mRadius);
                    }
                }
            });
            view.setClipToOutline(mRadius > 0);
        }
        view.invalidate();
    }

    public void setShadowAlpha(float shadowAlpha) {
        if (mShadowAlpha == shadowAlpha) {
            return;
        }
        mShadowAlpha = shadowAlpha;
        invalidateOutline();
    }

    private void invalidateOutline() {
        if (isUseShadow()) {
            View view = mCacheView.get();
            if (view == null) {
                return;
            }
            if (mShadowElevation == 0) {
                view.setElevation(0);
            } else {
                view.setElevation(mShadowElevation);
            }
            view.invalidateOutline();
        }
    }

    /**
     * 修改阴影颜色
     * >= Android 9.0才有效
     */
    private void setShadowColorInner(int shadowColor) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            View view = mCacheView.get();
            if (null != view) {
                view.setOutlineAmbientShadowColor(shadowColor);
                view.setOutlineSpotShadowColor(shadowColor);
            }
        }
    }

    /**
     * 设置阴影颜色
     */
    public void setShadowColor(int shadowColor) {
        if (mShadowColor != shadowColor) {
            mShadowColor = shadowColor;
            setShadowColorInner(mShadowColor);
        }
    }

    /**
     * 设置圆角
     * @param radius
     */
    public void setRadius(int radius) {
        if (mRadius == radius) {
            return;
        }
        setRadiusAndShadow(radius, mShadowElevation, mShadowAlpha);
    }

    /**
     * 需要 >= 21
     */
    private static boolean isUseShadow() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    }

}

/*
可以在 draw或者dispatchDraw 使用 PorterDuff.Mode，将控件变成多边形.
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
canvas.drawPath(clipPath, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
 */
